package middleware

import (
	"fmt"
	"net/http"
	"time"

	"github.com/dgrijalva/jwt-go/v4"
	"github.com/gin-gonic/gin"
)

//令牌解析的密钥
var mySigningKey = []byte("moretest")

//定义令牌存储的结构体内容
type MyCustomClaims struct {
	ID uint `json:"id"`
	jwt.StandardClaims
}

//创建随机生成的token令牌
func CreateToken(id uint) (string, bool) {

	// Create the Claims
	claims := MyCustomClaims{
		id,
		jwt.StandardClaims{
			ExpiresAt: jwt.NewTime(float64(time.Now().Add(15 * time.Hour).Unix())), // 传入的时间戳单位是秒
			IssuedAt:  jwt.NewTime(float64(time.Now().Unix())),
			Issuer:    "more",      // 颁发者
			Subject:   "more test", // 主题
		},
	}

	t := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	token, err := t.SignedString(mySigningKey)
	if err != nil {
		return "", false
	}

	return token, true
}

//验证密钥是否有效
func ParseToken(c *gin.Context) {
	token, err := jwt.ParseWithClaims(c.GetHeader("Authorization"), &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(mySigningKey), nil
	})
	//如果这里有错说明解析token失败了
	if err != nil {
		fmt.Println(err)
		c.JSON(http.StatusBadRequest, gin.H{
			"msg": "token校验未通过！",
		})
		c.Abort()
		return
	}
	//解析成功判断是否过期
	if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
		c.Set("userId", claims.ID)
		fmt.Printf("%v %v", claims.ID, claims.StandardClaims.ExpiresAt.Unix())
	} else {
		c.JSON(http.StatusUnauthorized, gin.H{
			"msg": "认证失效！",
		})
		c.Abort() //停止执行后面的亲戚
	}
}

// 专门用户webSocket 单独校验token的方法
func WsParseToken(Authorization string) (uint, bool) {

	token, err := jwt.ParseWithClaims(Authorization, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte("moretest"), nil
	})
	//如果这里有错说明解析token失败了
	if err != nil {
		fmt.Println(err)
		return 0, false
	}
	if claims, ok := token.Claims.(*MyCustomClaims); ok && token.Valid {
		fmt.Printf("%v %v", claims.ID, claims.StandardClaims.ExpiresAt.Unix())
		return claims.ID, true
	}
	return 0, false
}
